例えば React を JSX で書いているプロジェクトであれば JSX を使っているファイルでは必ずimport React from 'react';
のような書かなければいけません。( JSX 部分は変換されてReact.createElement
を使うようになる為)
設定する
ProvidePlugin
はwebpack
モジュールに付属しているので新たにインストールする必要はありません。これをplugins
セクションの中に置きます。
{
// ...略
plugins: [
new webpack.ProvidePlugin({
React: 'react'
})
]
}
ProvidePlugin
はオブジェクトを引数に取ります。その中にReact: 'react'
と置いた場合、「react
モジュールをReact
という名前でどこでも使えるようにするよ」という意味になります。JavaScript の場合設定はこれだけでどこでもReact
が使えるようになっているはずです。
ちなみに、どこでもはwebpack
のビルド対象ファイルだけで、window.React
という形にはならないので安全です。
対象のファイルをラップする親スコープがあり、そこにreact-WEBPACK-IMPORTED-MODULE-1-default
のような名前の関数が生えています。この関数は実行後にReact
モジュールを返し、これをReact
という名前で置く親スコープ内に置くことで使えるようになっているのだと思います。
ESLint を使っている場合はreact/react-in-jsx-scope
が引っかかるようになるかもしれません。これは"react/react-in-jsx-scope": 0
と ESLint のファイルに追記して無効化できます。
TypeScript 対応
TypeScript でどこでもReact
を使おうとすると、そのままではany
型になってしまいます。コード上ではいきなり現れた謎変数な為です。これにはアンビエント宣言(Ambient Declarations)を定義したファイルを作る必要があります。その中身は「どこでも出てくるReact
とは何ぞや」です。
アンビエント宣言はd.ts
という拡張子で作ります。「どこでも出てくる」は、つまりglobal
ということなのでd.ts
の置き場所はtsconfig
のinclude
パターンに含まれるか、files
の中に置かれていればどこでも大丈夫です。
React
だけならこれだけです。
import React from 'react';
// global 空間を拡張
declare global {
const React: typeof React;
}
これでどこでも型付きReact
が使えるようになったはずです。
ちなみにこっちは良くわからないですが駄目です。
import * as React from 'react';
declare var React: typeof React;
使った時にこのように警告されます。
'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.
「〜 import instead」この内容だと振り出しに戻るので却下です。なんだか難しいですが、モジュールのグローバル定義はdeclare global
で囲むことにします。